package baiqitun.stupro.common.service.support;

import baiqitun.stupro.common.exception.support.NotFoundException;
import baiqitun.stupro.common.mapper.TreeNodeMapper;
import baiqitun.stupro.common.model.TreeModel;
import baiqitun.stupro.common.model.vo.TreeNodeVo;
import baiqitun.stupro.common.service.TreeNodeVoService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.List;

/**
 * @author kedaji
 */
@Service
public class TreeNodeVoServiceImpl implements TreeNodeVoService {
    @Autowired
    private TreeNodeMapper treeNodeMapper;

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public TreeModel<TreeNodeVo> getTree(String id, String tableName) {
        TreeModel<TreeNodeVo> root = new TreeModel<>();
        List<TreeModel<TreeNodeVo>> trees = new LinkedList<>();

        for (TreeNodeVo treeNodeVo : getChildren(id, tableName)){
            trees.add(getTree(treeNodeVo.getId(),tableName));
        }
        root.setChildrenTree(trees);
        root.setNode(treeNodeMapper.selectTreeNodeVoById(id, tableName));
        return root;
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public TreeNodeVo getTopNode(String id, String tableName) {
        TreeNodeVo treeNodeVo = treeNodeMapper.selectTreeNodeVoById(id, tableName);
        if (treeNodeVo == null){
            throw new NotFoundException().put("id", id).put("tableName", tableName);
        }
        while (StringUtils.isNotBlank(treeNodeVo.getParentId())){
            treeNodeVo = treeNodeMapper.selectTreeNodeVoById(treeNodeVo.getId(), tableName);
        }
        return treeNodeVo;
    }

    private List<TreeNodeVo> getChildren(String id, String tableName){
        TreeNodeVo treeNodeVo = treeNodeMapper.selectTreeNodeVoById(id, tableName);
        if (treeNodeVo == null){
            throw new NotFoundException().put("id", id).put("tableName", tableName);
        }
        return treeNodeMapper.selectTreeNodeVoListByParentId(id, tableName);
    }
}
